package t_02_nio.group_chat;

import lombok.SneakyThrows;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;

public class GroupChatClient {
    public static void main(String[] args) throws Exception {
        GroupChatClient chatClient = new GroupChatClient("127.0.0.1", 6666);

        Thread thread = new Thread(chatClient::readInfo);
        thread.setDaemon(true);
        thread.start(); // 启动一个线程, 每个 3 秒，读取从服务器发送数据

        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()) {
            chatClient.sendInfo(scanner.nextLine()); // 发送数据给服务器端
        }
    }

    private final Selector selector;
    private final SocketChannel socketChannel;
    private final String username;

    public GroupChatClient(String host, Integer port) throws IOException { // 构造器, 完成初始化工作
        socketChannel = SocketChannel.open(new InetSocketAddress(host, port)); // 连接服务器
        socketChannel.configureBlocking(false); // 设置非阻塞
        selector = Selector.open();
        socketChannel.register(selector, SelectionKey.OP_READ); // 将 channel 注册到 selector
        username = socketChannel.getLocalAddress().toString().substring(1); // 得到 username
        System.out.println(username + " is ok...");
    }


    @SneakyThrows
    public void sendInfo(String info) { // 向服务器发送消息
        info = username + " 说：" + info;
        socketChannel.write(ByteBuffer.wrap(info.getBytes()));
    }

    @SneakyThrows
    public void readInfo() { // 读取从服务器端回复的消息
        while (true) {
            if (selector.select(3000) == 0) {
                System.out.println("等待了 3 秒，无服务端消息。当前注册的 selectionkey 数量 = " + selector.keys().size());
                continue;
            }

            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); // 有可以用的通道
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                if (key.isReadable()) {
                    SocketChannel sc = (SocketChannel) key.channel(); // 得到相关的通道
                    ByteBuffer buffer = ByteBuffer.allocate(1024); // 得到一个 Buffer
                    sc.read(buffer); // 读取
                    String msg = new String(buffer.array()); // 把读到的缓冲区的数据转成字符串
                    System.out.println(msg.trim());
                }
                iterator.remove(); // 删除当前的 selectionKey, 防止重复操作
            }
        }
    }
}
